<?php

namespace Wgx\Admin\Controller;

use Wgx\Admin\Com\AdminMenuRightsUtil;
use Wgx\Admin\Com\AdminSession;
use Wgx\Admin\Com\Crud\Crud;
use Wgx\Admin\Com\Crud\CrudField;
use Wgx\Admin\Com\Crud\CrudUserInterface;
use Wgx\Admin\Entity\AdminToMenuEntity;
use Wgx\Admin\Entity\AdminUserEntity;
use Wgx\Admin\Entity\UserEntity;
use PhpYes\Apps;
use PhpYes\Com\HttpException;
use PhpYes\Com\Router;
use PhpYes\Entity\BaseEntity;
use PhpYes\Modules\HTTP\Header\RequestHeader;
use Wgx\PdoEx\QueryBuilder;

class AdminUserController extends BaseController implements CrudUserInterface
{
    public function __construct()
    {
        /** @var Router $router */
        $router = \PhpYes\Apps::router();
        $func = $router->function;
        if ($func == 'login') {
            $this->auth = self::AuthNone;
        } elseif ($func == 'getListDataWithLoginAuth') {
            $this->auth = self::AuthLogin;
        }
    }

    /**
     * @return string
     * @throws HttpException
     */
    public function login()
    {
        $httpMethod = \PhpYes\Apps::getReqMethod();
        if ($httpMethod == 'GET') {
            $param = \PhpYes\Apps::getReqQueryParams();
            $referer = empty($param['referer']) ? null : trim($param['referer']);
            if (empty($referer)) {
                $referer = RequestHeader::getHeader('Referer');
                if ($referer) {
                    $referer = trim($referer);
                }
            }
            if (empty($referer)) {
                $referer = '/';
            }
            $data = array(
                'referer' => $referer,
            );

            return App::render()->display('adminuser/login.html.php', $data);
        } elseif ($httpMethod == 'POST' || $httpMethod == 'PUT') {
            $param = \PhpYes\Apps::getReqBodyParams();
            $username = empty($param['username']) ? null : trim($param['username']);
            if (empty($username)) {
                return App::render()->returnJsonWithErrorMessage('请传递用户名!', 481);
            }
            $password = empty($param['password']) ? null : trim($param['password']);
            if (empty($password)) {
                return App::render()->returnJsonWithErrorMessage('请传递密码!', 482);
            }

            $adminUserEntity = AdminUserEntity::getSingle()->findByEmail($username);
            if (empty($adminUserEntity)) {
                return App::render()->returnJsonWithErrorMessage('错误的用户名或密码!');
            }
            $myPass = $adminUserEntity->getPassword();
            if ($myPass != UserEntity::hashPassword($password)) {
                return App::render()->returnJsonWithErrorMessage('错误的用户名或密码!');
            }

            AdminSession::getSingleObj()->bindAdmin($adminUserEntity->getId());

            return App::render()->returnJsonSuccess();
        } else {
            throw new HttpException('错误的请求!');
        }
    }

    public function crud()
    {
        $crud = new Crud(AdminUserEntity::getSingle(), $this);

        $crud->addField(new CrudField('id', 'id', 'id', CrudField::ShowInAll))
            ->addField(new CrudField('createDt', '创建时间', '创建时间', CrudField::ShowInListPage | CrudField::ShowInReadPage | CrudField::ShowInExport))
            ->addField(new CrudField('name', '姓名', '姓名', CrudField::ShowInAll))
            ->addField(new CrudField('gender', '性别', '性别', CrudField::ShowInAll))
            ->addField(new CrudField('avatar', '头像', '头像', CrudField::ShowInAll))
            ->addField(new CrudField('phone', '手机号码', '手机号码', CrudField::ShowInAll))
            ->addField(new CrudField('email', '电子邮箱', '电子邮箱', CrudField::ShowInAll))
            ->addField(new CrudField('virtualIds', '关联的角色', '关联的角色', CrudField::ShowInAll));

        $rights = AdminMenuRightsUtil::getSingleObj()->getCurrentRights();
        if ($rights && ($rights & (AdminToMenuEntity::RightRead | AdminToMenuEntity::RightUpdate | AdminToMenuEntity::RightDelete)) > 0) {
            $crud->addField(new CrudField('operate', '操作', '', CrudField::ShowInListPage));
        }

        return $crud->execute();
    }

    /**
     * @inheritDoc
     */
    public function setForOp(Crud $crud, $extra)
    {
        $op = $crud->getOp();
        $op = empty($op) ? '' : trim($op);
        if ($op == 'listpage') {
            $this->setForGetListPage($crud);
        } elseif ($op == 'editpage') {
            $this->setForGetEditPage($crud, empty($extra['entity']) ? null : $extra['entity']);
        }
    }

    public function setForGetListPage(Crud $crud)
    {
        $crud->setPageDisplayTarget(Crud::PageReadPage, 'layer', '600px', '500px');
        $crud->setPageDisplayTarget(Crud::PageEditPage, 'layer', '600px', '500px');

        // ---------- 列表页(listpage) searchbar
        // $fieldMap = $crud->getFieldMap();
        // ----------

        // ---------- 列表页(listpage) 表格的字段设置
        $crud->getField('id')->setLpWidth('20px')->setLpIsSortable(true)->setLpClassName('dt-center');
        $crud->getField('createDt')->setLpWidth('60px')->setLpIsSortable(false)->setLpClassName('dt-center');
        $crud->getField('name')->setLpWidth('60px')->setLpIsSortable(false)->setLpClassName('dt-center');
        $crud->getField('gender')->setLpWidth('20px')->setLpIsSortable(false)->setLpRender(
            <<<'GENDERRENDER'
function (data, type, row, meta) {
  var gender = row.gender && parseInt(row.gender) || 0;
  if (gender == 1) {
    return '男';
  } else if (gender == 2) {
    return '女';
  } else {
    return '未知';
  }
}
GENDERRENDER
        )->setLpClassName('dt-center');
        $crud->getField('avatar')->setLpWidth('60px')->setLpIsSortable(false)->setLpClassName('dt-center');
        $crud->getField('phone')->setLpWidth('60px')->setLpIsSortable(false)->setLpClassName('dt-center');
        $crud->getField('email')->setLpWidth('60px')->setLpIsSortable(false)->setLpClassName('dt-center');
        $crud->getField('virtualIds')->setLpWidth('60px')->setLpIsSortable(false)->setLpClassName('dt-center');

        $operateField = $crud->getField('operate');
        if ($operateField) {
            $render = CrudField::getLpOperateRender($crud);
            $operateField->setLpWidth('100px')->setLpIsSortable(false)->setLpRender($render);
        }

        // ---------- 列表页(listpage) 表格的初始默认排序
        $crud->setLpOrder('id', 'desc');
    }

    public function setForGetEditPage(Crud $crud, $entity)
    {
    }

    /**
     * @inheritDoc
     */
    public function buildWhereForGetListData($params)
    {
        // TODO: Implement buildWhereForGetListData() method.
    }

    /**
     * @inheritDoc
     */
    public function buildOrderByForGetListData($fieldName, $direction)
    {
        // TODO: Implement buildOrderByForGetListData() method.
    }

    /**
     * @inheritDoc
     * @param AdminUserEntity $entity
     */
    public function formatData(Crud $crud, BaseEntity $entity, $context = null)
    {
        $op = $crud->getOp();
        $op = empty($op) ? '' : trim($op);
        if ($op == 'readpage') {
            $data = $entity->format(array(
                'create_dt' => 'createDt',
                'virtual_ids' => 'virtualIds'
            ));
        } elseif ($op == 'editpage') {
            $data = $entity->formatNormal();
        } else {
            $data = $entity->formatNormal();
        }

        return $data;
    }

    /**
     * @inheritDoc
     */
    public function formatListData(Crud $crud, $data, $context = null)
    {
        if (empty($data)) {
            return null;
        }

        $op = $crud->getOp();
        $op = empty($op) ? '' : trim($op);
        $newDataList = array();
        if ($op == 'listdata') {
            $formatMap = array(
                'create_dt' => 'createDt',
                'virtual_ids' => 'virtualIds'
            );
            foreach ($data as $item) {
                $entity = new AdminUserEntity($item);
                $newItem = $entity->format($formatMap);
                $newDataList[] = $newItem;
            }
        } elseif ($op == 'export') {
            $formatMap = array(
                'create_dt' => 'createDt',
                'virtual_ids' => 'virtualIds'
            );
            foreach ($data as $item) {
                $entity = new AdminUserEntity($item);
                $newItem = $entity->format($formatMap);
                $newDataList[] = $newItem;
            }
        } else {
            foreach ($data as $item) {
                $entity = new AdminUserEntity($item);
                $newItem = $entity->formatNormal();
                $newDataList[] = $newItem;
            }
        }
        return $newDataList;
    }

    /**
     * @inheritDoc
     */
    public function createOrUpdate(Crud $crud, BaseEntity $entity, $data)
    {
        // TODO: Implement createOrUpdate() method.
    }

    public function getListDataWithLoginAuth()
    {
        $param = \PhpYes\Apps::getReqQueryParams();

        $where = array();
        $name = empty($param['name']) ? null : trim($param['name']);
        if ($name) {
            $where['name'] = array('like' => "%{$name}%");
        }
        $gender = empty($param['gender']) ? 0 : intval($param['gender']);
        if ($gender) {
            $where['gender'] = $gender;
        }

        $orderBy = null;
        $orderFieldName = empty($param['_orderFieldName']) ? null : trim($param['_orderFieldName']);
        if ($orderFieldName) {
            $orderDirection = empty($param['_orderDirection']) ? 0 : intval($param['_orderDirection']);
            $orderBy = array($orderFieldName => empty($orderDirection) ? 'desc' : 'asc');
        }

        $entityTpl = AdminUserEntity::getSingle();
        $qb = QueryBuilder::useDb($entityTpl->getConnName());

        $limit = empty($param['_limit']) ? 10 : intval($param['_limit']);
        $offset = empty($param['_offset']) ? 0 : intval($param['_offset']);
        $qbResult = $qb->select($entityTpl->getTable(), 'SQL_CALC_FOUND_ROWS *', $where, null, $orderBy, $limit, $offset);
        $dataList = $qbResult->getPdoStatement()->fetchAll(\PDO::FETCH_ASSOC);
        $result = $qbResult->getPdo()->query('SELECT FOUND_ROWS() AS cnt;')->fetchAll(\PDO::FETCH_ASSOC);
        $total = empty($result[0]['cnt']) ? 0 : intval($result[0]['cnt']);
        $result = $dataList;
        if (empty($result)) {
            return App::render()->returnJson(array(
                'draw' => empty($param['_draw']) ? 0 : intval($param['_draw']),
                'total' => $total,
                'data' => array(),
            ));
        }

        $dataList = array();
        $class = get_class($entityTpl);
        foreach ($result as $item) {
            /** @var AdminUserEntity $entity */
            $entity = new $class($item);
            $dataList[] = $entity->formatNormal();
        }

        return App::render()->returnJson(array(
            'draw' => empty($param['_draw']) ? 0 : intval($param['_draw']),
            'total' => $total,
            'data' => $dataList,
        ));
    }
}